\begin{tikzpicture}

	\definecolor{appcolor}        {rgb}{1,1,0.7}
	\definecolor{guestoscolor}    {rgb}{0.8,0.8,0.7}
	\definecolor{defaultcolor}    {rgb}{1,1,1}
	\definecolor{criticalcolor}   {rgb}{0.9,0.5,0.4}
	\definecolor{kernelcolor}     {rgb}{0.6,0.8,0.7}
	\definecolor{drivercolor}     {rgb}{0.6,0.7,0.8}

	\tikzstyle{treenode} = [component, path fading=flow fade, align=center,
	                        rounded corners=1, minimum height=6ex]

	\tikzstyle{service} = [draw=black, draw opacity=0.4, ball color=defaultcolor, fill opacity=0.2,
	                       rounded corners=0, shape=semicircle,
	                       inner sep=1.3ex, outer sep=0, above]

	\tikzstyle{appnode}     = [treenode, bottom color=appcolor]
	\tikzstyle{kernelnode}  = [treenode, bottom color=kernelcolor, minimum width=80ex]
	\tikzstyle{drivernode}  = [treenode, bottom color=drivercolor]
	\tikzstyle{muxnode}     = [treenode, bottom color=criticalcolor]
	\tikzstyle{guestosnode} = [treenode, bottom color=guestoscolor, top color=appcolor]

	%
	% Components
	%

	% kernel
	\node[kernelnode] (kernel) {Kernel};

	% core / init
	\node[above=1ex of kernel, kernelnode] (core) {Core / Init};

	\path (core.north) node[service, xshift=-16ex, scale=0.4] (irqservice) {};
	\path (irqservice) node[scale=0.7, yshift=-2ex] {IRQ};

	\path (core.north) node[service, xshift=16ex, scale=0.4] (mmioservice) {};
	\path (mmioservice) node[scale=0.7, yshift=-2ex] {MMIO};

	% platform driver
	\node[drivernode, minimum width=80ex, above=4ex of core] (platformdrv) {Platform Driver};
	\path (platformdrv.north) node[service, scale=0.4] (platformservice) {};
	\path (platformdrv.north) node[scale=0.7, yshift=-1.5ex] {Platform};

	% drivers
	\node[drivernode, minimum width=26ex, above=4ex of platformdrv] (nicdrv)  {NIC Driver};
	\path (nicdrv.north) node[service, scale=0.4] (nicdrvservice) {};
	\path (nicdrvservice) node[scale=0.7, yshift=-2ex] {NIC};

	% NIC router
	\node[muxnode, minimum width=26ex, above=4ex of nicdrv] (nicrouter)  {NIC Router};
	\path (nicrouter.north) node[service, scale=0.4] (nicrouterservice) {};
	\path (nicrouterservice) node[scale=0.7, yshift=-2ex] {NIC};

	% app
	\node[appnode, minimum width=20ex, minimum height=12ex, above=8ex of nicrouter, xshift=-30ex] (nicapp) {};
	\path (nicapp.north)+(0,-3ex) node {Network Application};

	\node[draw, draw opacity=0.2, fill=black, fill opacity=0.1,
	      text opacity=1, rounded corners=2, anchor=south, at=(nicapp.south),
	      yshift=1ex] (tcpip) {TCP/IP Stack};

	\node[scale=0.7, at=(tcpip.north), anchor=south] {Socket API};

	% app
	\node[appnode, minimum width=20ex, minimum height=12ex, above=8ex of nicrouter, xshift=0ex] (nicapp2) {};
	\path (nicapp2.north)+(0,-3ex) node {Network Application};

	\node[draw, draw opacity=0.2, fill=black, fill opacity=0.1,
	      text opacity=1, rounded corners=2, anchor=south, at=(nicapp2.south),
	      yshift=1ex] (tcpip2) {TCP/IP Stack};

	\node[scale=0.7, at=(tcpip2.north), anchor=south] {Socket API};

	% virtual machine
	\node[appnode, minimum width=20ex, minimum height=6ex, above=8ex of nicrouter, xshift=30ex] (vmm) {};
	\node[at=(vmm.south), anchor=south, yshift=1ex] {Virtual Machine};

	\node[draw, draw opacity=0.2, fill=black, fill opacity=0.2, scale=0.75,
	      text opacity=1, rounded corners=2, anchor=north, at=(vmm.north)] (vnic) {vNIC};

	\node[guestosnode, minimum width=20ex, minimum height=6ex, anchor=south, at=(vmm.north)] (guestos) {Guest OS};

	\node[scale=0.7, at=(tcpip2.north), anchor=south] {Socket API};

	%
	% Sessions
	%
	\tikzstyle{treesessionarrow} = [arrow, thick]
	\path[treesessionarrow] (irqservice  |- platformdrv.south)   -- (irqservice);
	\path[treesessionarrow] (mmioservice |- platformdrv.south)   -- (mmioservice);
	\path[treesessionarrow] (tcpip2) -- (nicrouterservice);
	\path[treesessionarrow] (tcpip) .. controls +(0,-8ex) and +(-2ex,2ex) ..  (nicrouterservice);
	\path[treesessionarrow] (vnic) .. controls +(0,-8ex) and +(2ex,2ex) ..  (nicrouterservice);
	\path[treesessionarrow] (nicrouter) -- (nicdrvservice);
	\path[treesessionarrow] (platformservice |- nicdrv.south) -- (platformservice);

	\tikzstyle{details} = [rectangle callout, draw opacity=0.3, fill=white, fill opacity=0.2,
	                       text opacity=1, rounded corners=3, draw]

	\path (nicrouter.east)+(3ex,0ex)
		node [details, anchor=west, callout relative pointer={(-3ex,0ex)}, align=left] {
		- Packet routing\\
		- DHCP\\
		- Port forwarding\\
		- Link-state handling\\
		- Runtime-adjustable policy
		};

	\tikzstyle{risk} = [rectangle callout, fill=red!80!black, rounded corners=3, text=white]

	\path (nicdrv.north west)+(-3ex,4ex)
		node [risk, callout relative pointer={(3ex,-3ex)}, scale=1.5] {fragile};

\end{tikzpicture}
